//
//  TSCMyGCSelector.m
//  Tsc_IOS
//
//  Created by Rio on 15-6-9.
//  Copyright (c) 2015年 idream. All rights reserved.
//
//
// TODO 所有安卓中runOnUiThread，都被删除了，看看有没有必要加上
// TODO _spIdxGCId2DArr写死3了
// TODO UI显示的padding、宽度自适应问题
// TODO 当什么都不初始化时，maxRows==0，但依然添加了一个空行
// TODO 当宽度设置为280时，spinner的item中多了一条竖线？
// TODO 两条横向分隔符，为什么总是为总宽度？哪怕self.w已经变小了？
//L
// -- TODO 检查所有TODO
// -- TODO 如果2级分类为空时，2级分类的OnItemSelectedListener事件不会自动触发，则需要通过代码：IOS未必这样
// -- TODO spinner中元素如果不到5个，还是会显示后面元素下方的分割线
// -- TODO 在addSelectorRowSelected()中，需要将事件注册放在填充数据之后，如何进行？其他方法是否也会有同样的问题？
// xx TODO 数据未准备完毕前，_spIdxGCId2DArr不可用！
// -- TODO 检查TSCMyDBUtil
// -- TODO 各个类属性没有初始化就使用，有问题吗？
// -- TODO 在setSpinnerAdapter()中，可能不能使用异步线程，否则将导致多线程问题，后续显示不正常。因为安卓中这两段代码是顺序执行的
// -- TODO MySpinner中的回调，应该把自身传入，而不仅仅只是IndexPath

//#import "TSCMyGCSelector.h"
//#import "TSCMySpinner.h"
//#import "TSCMyUIUtil.h"
//#import "TSCMyClickBtn.h"
//#import "TSCMyDBUtil.h"
//#import "TSCMyUtil.h"
//#import "TSCMyDBHelper.h"
//#import "TSCConstants.h"
//#import "TSCJsonGC.h"
//#import "UIView+My.h"
//#import "TSCMyObserverLinerLayoutWH.h"
//#import "TSCLinearLayout2.h"
//
//
//
//#define MAX_GC_NUM 3 // 最大可选商品分类数量
//#define MAX_SP_NUM 3 // 最大商品分类级别（即spinner的最大个数）
//
//// 注：编码时模拟器为iPhone4，屏幕总宽度为320，在Storyborad中拖拽的默认UI元素宽度（左右两边已经有padding了）为300，所以也设置MyGCSelector的宽度为300
////#define UI_LABLE_W 270 // 说明文字宽度 == 300 - 30
//#define UI_E_H 30 // UI元素高度
////#define UI_SP_W 85 // spinner宽度 == (300 - 30 - 5 * 3) / 3
//#define UI_FONT_SIZE 13 // 字体大小
//#define UI_V_PADDING 5 // 各UI元素的上下间距
//#define UI_H_PADDING 5 // 各UI元素的左右间距
//
//
//@implementation TSCMyGCSelector {
//    UILabel * _lbIntro; // 首行说明文字（不包括右侧添加按钮）
//    TSCMyClickBtn * _btnAddGC;
//    TSCLinerLayout * _llAddGCPanel;
//    TSCLinerLayout * _hlsBottom;
//    
//    int _selectorRows; // 当前界面上有多少个商品分类选择器
//    
//    NSString * _allAvailableGCIds; // 如果传入了aAvailableGCIds，则找到所有可选择的商品分类id。这些id可能是aAvailableGCIds中的父类、爷爷类
//    
//    // 首次从APP_DB中读取的一、二、三级商品分类。最大支持三级
//	NSArray * _jsonGCList1; // 一级分类的全部商品分类，如果没有则为null
//    
//	int _spIdxGCId2DArr [MAX_GC_NUM][MAX_SP_NUM]; // 注：如果数组元素没有初始化，通过下标依然可以访问（甚至超出下标），但得到的值无意义
//    
//    InnerObserverGCSelectorWH * _observerGC;
//}
//

//- (id)initWithFrame:(CGRect)frame {
//    self = [super initWithFrame:frame];
//    if (self) {
//        // Initialization code
//        
//        // 自定义初始化
//        [self initGCSelector];
//    }
//    return self;
//}
//
//- (id) init {
//    //    self = [super init];
//    //    if (self) {
//    //
//    //        // 自定义初始化
//    //      [self myInit2];
//    //    }
//    // 注：通过自身的initWithFrame，将初始化入口都定为initWithFrame，可以保证myInit只被调用一次
//    self = [self initWithFrame:CGRectMake(0, 0, 0, 0)];
//    return self;
//}
//
//// 注：该方法不能与父类LinerLayout（后简称LL）中的方法myInit同名！因为调用[super init]时，此时代码虽然运行在父类LL中，但self指向的对象其实还是子类GCSelector（OC机制就是这样，无法避免。我已经通过3层继承试验过）。所以当在父类LL中调用[self myInit]时，其实调用的是子类的myInit（其实就是方法重写），但当前上下文中，应该调用父类LL的myInit。而在父类LL中不能写成[super myInit]，因为父类LL的父类是UIView，而UIView没有myInit方法。为了解决这一问题，只能将子类中的同名方法换一个名字。并且将来如果还有孙子类继承GCSelector，也要注意这个问题，还得换另一个名字。
///* private */ - (void) initGCSelector {
//    // 如果调用了没有任何参数的构造函数，则所有属性赋值默认值
//    _maxRows = 0; // 先设置为0，后续读取APP_DB中的配置
//    _availableGCIds = @"";
//    _selectedGCIds = @"";
//    
//    _selectorRows = 0;
//    
//    // 因oc中没有初始化的primitve数组的值是无效的，所以需要手工初始化
//    for (int i = 0; i < MAX_GC_NUM; i++) {
//        for (int j = 0; j < MAX_SP_NUM; j++) {
//            _spIdxGCId2DArr[i][j] = 0;
//        }
//    }
//    
//    // ===== 创建UI元素
//    
//    // 创建顶部：左侧label
//    _lbIntro = [[UILabel alloc]init];
////    lb.frame = CGRectMake(0, 0, UI_LABLE_W, UI_E_H);
//    _lbIntro.frame = CGRectMake(0, 0, [self calculateLbW], UI_E_H);
//    _lbIntro.font = [UIFont fontWithName:[TSCMyUIUtil getSystemDefaultFont].fontName size:UI_FONT_SIZE];
//    _lbIntro.text = NSLocalizedString(@"hint_select_goods_class", nil);
//    
//    // 创建顶部：右侧按钮
//    _btnAddGC = [TSCMyClickBtn buttonWithType:UIButtonTypeSystem]; // 确保点击时产生阴影
//    _btnAddGC.frame = CGRectMake(0, 0, UI_E_H, UI_E_H);
//    [_btnAddGC setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
//    [_btnAddGC setTitle:NSLocalizedString(@"btn_plus", nil) forState:UIControlStateNormal];
////    _btnAddGC.titleLabel.font = [UIFont fontWithName:[TSCMyUIUtil getSystemDefaultFont].fontName size:50]; // TODO
//    _btnAddGC.backgroundColor = COLOR_MT;
//    [TSCMyUIUtil setUIRoundRectBG:_btnAddGC radius:10.0]; // 设置圆形按钮
//    
//    // 创建顶部
//    TSCLinearLayout2 * llTop = [[TSCLinearLayout2 alloc]init];
//    [llTop addSubview:_lbIntro];
//    [llTop addSubview:_btnAddGC];
//    
//    // 创建顶部分割线
//    TSCLinerLayout * hlsTop = [TSCMyUIUtil createHLS];
//    
//    // 创建中部
//    _llAddGCPanel = [[TSCLinearLayout2 alloc]init];
//    _llAddGCPanel.orientation = LinerLayoutOrientationVertical;
//    _llAddGCPanel.layoutWidth = LayoutWHTypeWrapContent;
//    _llAddGCPanel.layoutHeight = LayoutWHTypeWrapContent;
//    _llAddGCPanel.vPadding = UI_V_PADDING;
//    
//    // 创建底部分割线
//    _hlsBottom = [TSCMyUIUtil createHLS];
//    
//    // 创建根view
//    TSCLinerLayout * llRoot = [[TSCLinerLayout alloc]init];
//    llRoot.orientation = LinerLayoutOrientationVertical;
//    llRoot.layoutWidth = LayoutWHTypeMatchParent; // 注：必须为match_parent，因为当self.w变化时，还需要同步变化也为LinerLayout的分割线
//    llRoot.layoutHeight = LayoutWHTypeWrapContent;
//    llRoot.vPadding = UI_V_PADDING;
//    
//    [llRoot addSubview:llTop];
//    [llRoot addSubview:hlsTop];
//    [llRoot addSubview:_llAddGCPanel];
//    [llRoot addSubview:_hlsBottom];
//    NSLog(@"llRoot:%@", llRoot);
//    
//    // 设置最外层（自身）
//    self.orientation = LinerLayoutOrientationVertical;
//    self.layoutWidth = LayoutWHTypeWrapContent;
//    self.layoutHeight = LayoutWHTypeWrapContent;
//    [self addSubview:llRoot];
//    
//    // 增加一个空行
//    [self addSelectorRowEmpty];
//    
//    // 重新计算说明文字的宽度（因为此时才能获得正确地self.w）
//    // 注：暂时注释，因为后续还有机会重新设置说明文字的宽度
////    _lbIntro.frame = CGRectMake(0, 0, [self calculateLbW], UI_E_H);
//    
//    [self registerEvents];
//    
//    // 增加监听者
////    _observerGC = [[InnerObserverGCSelectorWH alloc]initWithGCSelector:self];
////    [self addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
////    [self addObserver:self forKeyPath:@"bounds" options:NSKeyValueObservingOptionNew context:nil];
//}
//
////- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
////    [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
////    
////    if ([keyPath isEqualToString:@"frame"]) {
////        [self refreshUI];
////    } else if ([keyPath isEqualToString:@"bounds"]) {
////        [self refreshUI];
////    }
////}
//
////- (void) setFrame:(CGRect)frame {
////    CGRect oldFrame = self.frame;
////    
////    [super setFrame:frame];
////    
////    // 如果宽度或者高度变化了，则需要重新刷新界面，以改变首行说明文字宽度、spinner宽度
////    if (_llAddGCPanel == nil) {
////        return;
////    }
////    if (oldFrame.size.width != frame.size.width || oldFrame.size.height != frame.size.height) {
////        [self refreshUI];
////    }
////}
//
//- (void) dealloc {
//    [_observerGC removeObserver];
//}
//
///*
// // Only override drawRect: if you perform custom drawing.
// // An empty implementation adversely affects performance during animation.
// - (void)drawRect:(CGRect)rect
// {
// // Drawing code
// }
// */
//
//#pragma mark 私有方法
//
///* private */ - (void) registerEvents {
//    
//    // 注册事件——增加商品分类选择器
//    __weak typeof (self) _weakSelf = self;
//    _btnAddGC.btnClickedListener = ^(TSCMyClickBtn * btn) {
//        typeof (self) _strongSelf = _weakSelf;
//        if (_strongSelf) {
//            // 检查是否超过最大行数限制
//            if (_strongSelf->_selectorRows >= _strongSelf->_maxRows) {
//                NSString * msg = [NSString stringWithFormat:@"%@%i%@", NSLocalizedString(@"err_exceed_max_selectable_goods_class_1", nil),_strongSelf->_maxRows, NSLocalizedString(@"err_exceed_max_selectable_goods_class_2", nil)];
//                [TSCMyUIUtil popErrWithString:msg];
//                return;
//            }
//            
//            // 增加一个空行
//            [_weakSelf addSelectorRowUnselected];
//        } else {
//            NSLog(@"[W]%s: block中的弱引用为nil，导致block内部代码无法正常执行！", __FUNCTION__);
//        }
//    };
//}
//
///**
// * 过滤aMaxRows。注：
// * <p>
// * 1. 每一次重新设置aMaxRows后，都需要调用此方法
// */
///* private */ - (int) filterMaxRows:(int)maxRows {
//    if (maxRows < 0) {
//        // 记录log并提示错误
//        NSLog(@"[w]%s:aMaxRows不能小于0（等于0时使用系统默认值）！将使用系统默认值代替错误值", __FUNCTION__);
//        [TSCMyUIUtil popErrWithResourceKey:@"err_system_gc_selector"];
//        NSDictionary * dic = [TSCMyDBUtil getSysConfigValueBatch_1:[NSArray arrayWithObject:DB_SYS_CONFIG_KEY_MAX_SELECTABLE_GOODS_CLASS]];
//        return [[dic objectForKey:DB_SYS_CONFIG_KEY_MAX_SELECTABLE_GOODS_CLASS] intValue];
//    } else if (maxRows == 0) {
//        NSDictionary * dic = [TSCMyDBUtil getSysConfigValueBatch_1:[NSArray arrayWithObject:DB_SYS_CONFIG_KEY_MAX_SELECTABLE_GOODS_CLASS]];
//        return [[dic objectForKey:DB_SYS_CONFIG_KEY_MAX_SELECTABLE_GOODS_CLASS] intValue];
//    } else {
//        return maxRows;
//    }
//}
//
///**
// * 公共过滤方法：对aAvailableGCIds、aSelectedGCIds进行过滤。注：
// * <p>
// * 1. 每一次重新设置aAvailableGCIds或aSelectedGCIds后，都需要调用此方法
// */
///* private */ - (NSString *) filterGCIds_1:(NSString *)gcIds {
//    if ([TSCMyUtil isStringEmpty:gcIds] == true) {
//        return @"";
//    }
//    
//    NSString * tn = DB_TABLE_NAME_GOODS_CLASS;
//    
//    // （1）检查：状态为启用+存在于APP_DB中
//    NSString * sql = [NSString stringWithFormat:
//                      @"SELECT id FROM %@ WHERE status = %i AND id IN (%@);",
//                      tn,
//                      DB_GOODS_CLASS_STATUS_IN_USE,
//                      gcIds
//                      ];
//    NSArray * idDicArray = [TSCMyDBHelper selectWithSql:sql];
//    NSMutableArray * inIdArray = [NSMutableArray array];
//    for (NSDictionary * idDic in idDicArray) {
//        [inIdArray addObject:[idDic objectForKey:@"id"]];
//    }
//    
//    // （2）检查：不能是4级及以下级的商品分类
//    sql = [NSString stringWithFormat:
//           @"SELECT A3.id FROM %@ AS A3, %@ AS A2, %@ AS A1 WHERE A3.pid = A2.id AND A2.pid = A1.id AND A1.pid != 0;",
//           tn,
//           tn,
//           tn
//           ];
//    NSArray * excludeIdDicArray = [TSCMyDBHelper selectWithSql:sql];
//    for (NSDictionary * excludeIdDic in excludeIdDicArray) {
//        NSObject * Id = [excludeIdDic objectForKey:@"id"] ;
//        if ([inIdArray containsObject:Id]) {
//            // 注：这里移除的应该是对象，而不是从位置为index的地方移除元素
//            [inIdArray removeObject:Id];
//        }
//    }
//    
//    // （3）检查：不能再含有子分类
//    // 注：过滤时，不要把pid为3级分类的情况也过滤掉了。因为虽然某个3级分类包含4级分类，但这个3级分类也是合法的（可被选择的）
//    sql = [NSString stringWithFormat:
//           @"SELECT pid FROM %@ WHERE pid IN (%@) AND pid NOT IN (%@) GROUP BY pid;",
//           tn,
//           [TSCMyUtil implodeWithGlue:@"," array:inIdArray],
//           // -- 嵌套：找到所有3级分类id，将其排除在外
//           [NSString stringWithFormat:@"SELECT A3.id AS id FROM %@ AS A3, %@ AS A2, %@ AS A1 WHERE A3.pid = A2.id AND A2.pid = A1.id AND A1.pid = 0", tn, tn, tn]
//           ];
//    NSArray * excludePidDicArray = [TSCMyDBHelper selectWithSql:sql];
//    for (NSDictionary * excludePidDic in excludePidDicArray) {
//        NSObject * pid = [excludePidDic objectForKey:@"pid"];
//        if ([inIdArray containsObject:pid]) {
//            // 注：这里移除的应该是对象，而不是从位置为index的地方移除元素
//            [inIdArray removeObject:pid];
//        }
//    }
//    
//    return [TSCMyUtil implodeWithGlue:@"," array:inIdArray];
//}
//
///**
// * 检查aSelectedGCIds是否大于aMaxRows。注：
// * <p>
// * 此方法必须在过滤了aAvailableGCIds、aSelectedGCIds之后再调用
// */
///* private */ - (void) checkMaxRowsLargerSelectedGCIds {
//    // 注：当设置了默认被选项时，才进行校验
//    if ([TSCMyUtil isStringEmpty:_selectedGCIds] == false) {
//        NSArray * selectedIdArr = [TSCMyUtil explodeString:_selectedGCIds delimiter:@","];
//        
//        if ([selectedIdArr count] > _maxRows) {
//            NSLog(@"[W]%s: aSelectedGCIds的数量不能大于aMaxRows！将清除aSelectedGCIds", __FUNCTION__);
//            _selectedGCIds = @"";
//            [TSCMyUIUtil popErrWithResourceKey:@"err_system_gc_selector"];
//        }
//    }
//}
//
///**
// * 检查aSelectedGCIds是否是aAvailableGCIds的子集
// */
///* private */ - (void) checkSelectedGCIdsInAvailableGCIds {
//    // 注：当设置了默认被选项、且设置了选择范围时，才进行校验
//    if ([TSCMyUtil isStringEmpty:_selectedGCIds] == false && [TSCMyUtil isStringEmpty:_availableGCIds] == false) {
//        NSArray * selectedIdArr = [TSCMyUtil explodeString:_selectedGCIds delimiter:@","];
//        NSArray * availableIdArr = [TSCMyUtil explodeString:_availableGCIds delimiter:@","];
//        if ([TSCMyUtil isA:selectedIdArr subsetOfB:availableIdArr] == false) {
//            NSLog(@"[W]%s: aSelectedGCIds必须是aAvailableGCIds的子集！将清除aSelectedGCIds", __FUNCTION__);
//            _selectedGCIds = @"";
//            [TSCMyUIUtil popErrWithResourceKey:@"err_system_gc_selector"];
//        }
//    }
//}
//
//
///* private */ - (void) addSelectorRowEmpty {
//    
//    // ===== 创建一行选择器
//    
//    // 创建3个sp
//    TSCMySpinner * sp1 = [[TSCMySpinner alloc]init];
//    TSCMySpinner * sp2 = [[TSCMySpinner alloc]init];
//    TSCMySpinner * sp3 = [[TSCMySpinner alloc]init];
//    sp1.frame = sp2.frame = sp3.frame = CGRectMake(0, 0, [self calculateSPW], UI_E_H);
//    sp1.font = sp2.font = sp3.font = [UIFont fontWithName:[TSCMyUIUtil getSystemDefaultFont].fontName size:UI_FONT_SIZE];
//    
//    // 创建删除按钮
//    TSCMyClickBtn * btnDelGC = [TSCMyClickBtn buttonWithType:UIButtonTypeSystem];  // 确保点击时产生阴影
//    btnDelGC.frame = CGRectMake(0, 0, UI_E_H, UI_E_H);
//    [btnDelGC setImage:[UIImage imageNamed:@"ic_err_96x96.png" ] forState:UIControlStateNormal];
//    
//    
//    // 创建ll
//    TSCLinerLayout * selectorRow = [[TSCLinerLayout alloc]init];
//    selectorRow.orientation = LinerLayoutOrientationHorizontal;
//    selectorRow.layoutWidth = LayoutWHTypeWrapContent;
//    selectorRow.layoutHeight = LayoutWHTypeWrapContent;
//    selectorRow.hPadding = UI_H_PADDING;
//    
//    // 添加到界面
//    [selectorRow addSubview:sp1];
//    [selectorRow addSubview:sp2];
//    [selectorRow addSubview:sp3];
//    [selectorRow addSubview:btnDelGC];
//    [_llAddGCPanel addSubview:selectorRow];
//    
//    // 仅显示第一个sp
//    sp1.hidden = NO;
//    sp2.hidden = YES;
//    sp3.hidden = YES;
//    
//    // 注册事件——删除按钮
//    btnDelGC.btnClickedListener = ^(TSCMyClickBtn * btn) {
//        [selectorRow removeFromSuperview]; // 品类选择view所在的父view也是固定的
//        
//        // 更新计数
//        _selectorRows--;
//        
//        // 判断是否需要显示底部的分隔符
//        if (_selectorRows == 0) {
//            _hlsBottom.hidden = YES;
//        }
//    };
//    
//    // 更新计数
//    _selectorRows++;
//    
//    // 判断是否需要显示底部的分隔符
//    if (_selectorRows > 0) {
//        _hlsBottom.hidden = NO;
//    }
//}
//
///* private */ - (void) addSelectorRowUnselected {
//    
//    // 增加一行选择器
//    TSCLinerLayout * selectorRow = [[TSCLinerLayout alloc]init];
//    selectorRow.orientation = LinerLayoutOrientationHorizontal;
//    selectorRow.layoutWidth = LayoutWHTypeWrapContent;
//    selectorRow.layoutHeight = LayoutWHTypeWrapContent;
//    selectorRow.hPadding = UI_H_PADDING;
//    
//    // 创建3个sp
//    TSCMySpinner * sp1 = [[TSCMySpinner alloc]init];
//    TSCMySpinner * sp2 = [[TSCMySpinner alloc]init];
//    TSCMySpinner * sp3 = [[TSCMySpinner alloc]init];
//    sp1.frame = sp2.frame = sp3.frame = CGRectMake(0, 0, [self calculateSPW], UI_E_H);
//    sp1.font = sp2.font = sp3.font = [UIFont fontWithName:[TSCMyUIUtil getSystemDefaultFont].fontName size:UI_FONT_SIZE];
//    
//    
//    // 创建删除按钮
//    TSCMyClickBtn * btnDelGC = [TSCMyClickBtn buttonWithType:UIButtonTypeSystem];  // 确保点击时产生阴影
//    btnDelGC.frame = CGRectMake(0, 0, UI_E_H, UI_E_H);
//    [btnDelGC setImage:[UIImage imageNamed:@"ic_err_96x96.png" ] forState:UIControlStateNormal];
//    
//    // 注册事件——删除此行品类选择器
//    btnDelGC.btnClickedListener = ^(TSCMyClickBtn * btn) {
//        [selectorRow removeFromSuperview]; // 品类选择view所在的父view也是固定的
//        
//        // 更新计数
//        _selectorRows--;
//        
//        // 判断是否需要显示底部的分隔符
//        if (_selectorRows == 0) {
//            _hlsBottom.hidden = YES;
//        }
//    };
//    
//    // 添加到界面
//    [selectorRow addSubview:sp1];
//    [selectorRow addSubview:sp2];
//    [selectorRow addSubview:sp3];
//    [selectorRow addSubview:btnDelGC];
//    [_llAddGCPanel addSubview:selectorRow];
//    
//    // 注册事件——1级分类变化时，自动获取其下所有2级分类
//    [self registerSpinner1Events:sp1 sp2:sp2 sp3:sp3];
//    
//    // 注册事件——2级分类变化时，自动获取其下所有3级分类
//    [self registerSpinner2Events:sp1 sp2:sp2 sp3:sp3];
//    
//    // 注册事件——3级分类变化时，在整行选择器上保存选择了哪一个商品分类
//    [self registerSpinner3Events:sp1 sp2:sp2 sp3:sp3];
//    
//    // 初始化sp1。sp2、sp3将因为OnItemSelectedListener()事件而自动选择
//    [self setSpinnerAdapter:sp1 jsonGCList:_jsonGCList1];
//    
//    // 更新计数
//    _selectorRows++;
//    
//    // 判断是否需要显示底部的分隔符
//    if (_selectorRows > 0) {
//        _hlsBottom.hidden = NO;
//    }
//}
//
///* private */ - (void) addSelectorRowSelected:(int[3]) spIdxGcIdArr {
//    
//    // 增加一行选择器
//    TSCLinerLayout * selectorRow = [[TSCLinerLayout alloc]init];
//    selectorRow.orientation = LinerLayoutOrientationHorizontal;
//    selectorRow.layoutWidth = LayoutWHTypeWrapContent;
//    selectorRow.layoutHeight = LayoutWHTypeWrapContent;
//    selectorRow.hPadding = UI_H_PADDING;
//    
//    // 创建3个sp
//    TSCMySpinner * sp1 = [[TSCMySpinner alloc]init];
//    TSCMySpinner * sp2 = [[TSCMySpinner alloc]init];
//    TSCMySpinner * sp3 = [[TSCMySpinner alloc]init];
//    sp1.frame = sp2.frame = sp3.frame = CGRectMake(0, 0, [self calculateSPW], UI_E_H);
//    sp1.font = sp2.font = sp3.font = [UIFont fontWithName:[TSCMyUIUtil getSystemDefaultFont].fontName size:UI_FONT_SIZE];
//    
//    // 注册事件——删除此行品类选择器
//    TSCMyClickBtn * btnDelGC = [TSCMyClickBtn buttonWithType:UIButtonTypeSystem];  // 确保点击时产生阴影
//    btnDelGC.frame = CGRectMake(0, 0, UI_E_H, UI_E_H);
//    [btnDelGC setImage:[UIImage imageNamed:@"ic_err_96x96.png" ] forState:UIControlStateNormal];
//    
//    // 注册事件——删除此行品类选择器
//    btnDelGC.btnClickedListener = ^(TSCMyClickBtn * btn) {
//        [selectorRow removeFromSuperview]; // 品类选择view所在的父view也是固定的
//        
//        // 更新计数
//        _selectorRows--;
//        
//        // 判断是否需要显示底部的分隔符
//        if (_selectorRows == 0) {
//            _hlsBottom.hidden = YES;
//        }
//    };
//    
//    // 添加到界面
//    [selectorRow addSubview:sp1];
//    [selectorRow addSubview:sp2];
//    [selectorRow addSubview:sp3];
//    [selectorRow addSubview:btnDelGC];
//    [_llAddGCPanel addSubview:selectorRow];
//    
//    // 获得3个商品分类id
//    int selectedGCId1 = spIdxGcIdArr[0];
//    int selectedGCId2 = spIdxGcIdArr[1];
//    int selectedGCId3 = spIdxGcIdArr[2];
//    
//    // 处理sp1
//    if (selectedGCId1 != 0) {
//        // 找到sp1选择item对应的全部二级商品分类
//        // 注：mJsonGCList1在之前初始化过
//        
//        // 填充sp
//        [self setSpinnerAdapter:sp1 jsonGCList:_jsonGCList1];
//        
//        // 找到gcId在spinner中对应的itemIdex
//        int selectedItemIndex = 0;
//        for (int i = 0, max = [_jsonGCList1 count]; i < max; i++) {
//            if (((TSCJsonGC *)[_jsonGCList1 objectAtIndex:i]).Id == selectedGCId1) {
//                selectedItemIndex = i;
//                break;
//            }
//        }
//        
//        // 在sp中选择指定的item
//        [sp1 setSelectedItem:selectedItemIndex];
//        
//        // 在整行选择器上保存商品分类id
//        selectorRow.myTag = [NSNumber numberWithInt:selectedGCId1];
//    }
//    
//    // 处理sp2
//    if (selectedGCId2 != 0) {
//        // 找到sp1选择item对应的全部二级商品分类
//        NSArray * jsonGCList2 = [TSCMyDBUtil getGoodsClassAllChildrenInUse_1:selectedGCId1 availableGCIds:_allAvailableGCIds];
//        
//        // 填充sp
//        [self setSpinnerAdapter:sp2 jsonGCList:jsonGCList2];
//        
//        // 找到gcId在spinner中对应的itemIdex
//        int selectedItemIndex = 0;
//        for (int i = 0, max = [jsonGCList2 count]; i < max; i++) {
//            if (((TSCJsonGC *)[jsonGCList2 objectAtIndex:i]).Id == selectedGCId2) {
//                selectedItemIndex = i;
//                break;
//            }
//        }
//        
//        // 在sp中选择指定的item
//        [sp2 setSelectedItem:selectedItemIndex];
//        
//        // 在整行选择器上保存商品分类id
//        selectorRow.myTag = [NSNumber numberWithInt:selectedGCId2];
//    }
//    
//    // 处理sp3
//    if (selectedGCId3 != 0) {
//        // 找到sp1选择item对应的全部二级商品分类
//        NSArray * jsonGCList3 = [TSCMyDBUtil getGoodsClassAllChildrenInUse_1:selectedGCId2 availableGCIds:_allAvailableGCIds];
//        
//        // 填充sp
//        [self setSpinnerAdapter:sp3 jsonGCList:jsonGCList3];
//        
//        // 找到gcId在spinner中对应的itemIdex
//        int selectedItemIndex = 0;
//        for (int i = 0, max = [jsonGCList3 count]; i < max; i++) {
//            if (((TSCJsonGC *)[jsonGCList3 objectAtIndex:i]).Id == selectedGCId3) {
//                selectedItemIndex = i;
//                break;
//            }
//        }
//        
//        // 在sp中选择指定的item
//        [sp3 setSelectedItem:selectedItemIndex];
//        
//        // 在整行选择器上保存商品分类id
//        selectorRow.myTag = [NSNumber numberWithInt:selectedGCId3];
//    }
//    
//    // 注册事件
//    // 注意：一定要在填充完sp之后才能注册事件，否则会导致在填充sp时，就触发事件，引起不必要的混乱
//    // 如果仅仅只是注册事件的代码放在setSelection()之后是没有用的，必须使用post()方法才能保证注册事件在setSelection()之后
//    
//    // 注册事件——1级分类变化时，自动获取其下所有2级分类
//    [self registerSpinner1Events:sp1 sp2:sp2 sp3:sp3];
//    // 注册事件——2级分类变化时，自动获取其下所有3级分类
//    [self registerSpinner2Events:sp1 sp2:sp2 sp3:sp3];
//    // 注册事件——3级分类变化时，在整行选择器上保存选择了哪一个商品分类
//    [self registerSpinner3Events:sp1 sp2:sp2 sp3:sp3];
//    
//    
//    // 更新计数
//    _selectorRows++;
//    
//    // 判断是否需要显示底部的分隔符
//    if (_selectorRows > 0) {
//        _hlsBottom.hidden = NO;
//    }
//}
//
//
///**
// * 注册事件——1级分类变化时，自动获取其下所有2级分类
// *
// * @param sp1
// * @param sp2
// * @param sp3
// */
///* private */ - (void) registerSpinner1Events:(TSCMySpinner *)sp1 sp2:(TSCMySpinner *)sp2 sp3:(TSCMySpinner *)sp3 {
//    sp1.itemSelectedListener = ^(TSCMySpinner * sp, UITableViewCell * cell, NSIndexPath * ip) {
//        // 获得tag
//        TSCJsonGC * jsonGC = (TSCJsonGC *) cell.myTag;
//        
//        // 在整行选择器上保存商品分类id
//        // 注（安卓）：此时，view是spinner中的item：textview；parent是spinner本身；parent.getParent()是整行选择器
//        // 注（IOS）：spinner的parent就是整行选择器
//        TSCLinerLayout * selectorRow = (TSCLinerLayout *) sp.superview;
//        selectorRow.myTag = [NSNumber numberWithInt:jsonGC.Id];
//        
//        // 重新设置2级分类
//        NSArray * jsonGCArray2 = [TSCMyDBUtil getGoodsClassAllChildrenInUse_1:jsonGC.Id availableGCIds:_allAvailableGCIds];
//        [self setSpinnerAdapter:sp2 jsonGCList:jsonGCArray2];
//        
//        // 如果2级分类为空时，2级分类的OnItemSelectedListener事件不会自动触发，则需要通过代码（安卓如此，IOS的MySpinner是自己写的：当dataArray为空时，不会进行自动选择，也是如此。所以可以推测，安卓的Spinner代码写法，跟我的写法应该是一样的）
//        // 隐藏3级分类
//        if ([jsonGCArray2 count] == 0) {
//            [self setSpinnerAdapter:sp3 jsonGCList:nil]; // 直接隐藏3级分类选择器
//        }
//    };
//}
//
///**
// * 注册事件——2级分类变化时，自动获取其下所有3级分类
// *
// * @param sp1
// * @param sp2
// * @param sp3
// */
///* private */ - (void) registerSpinner2Events:(TSCMySpinner *)sp1 sp2:(TSCMySpinner *)sp2 sp3:(TSCMySpinner *)sp3 {
//    sp2.itemSelectedListener = ^(TSCMySpinner * sp, UITableViewCell * cell, NSIndexPath * ip) {
//        // 获得tag
//        TSCJsonGC * jsonGC = (TSCJsonGC *) cell.myTag;
//        
//        // 在整行选择器上保存商品分类id
//        // 注：此时，view是spinner中的item：textview；parent是spinner本身；parent.getParent()是整行选择器
//        // 注（IOS）：spinner的parent就是整行选择器
//        TSCLinerLayout * selectorRow = (TSCLinerLayout *) sp.superview;
//        selectorRow.myTag = [NSNumber numberWithInt:(jsonGC.Id)];
//        
//        // 重新设置3级分类
//        NSArray * jsonGCArray3 = [TSCMyDBUtil getGoodsClassAllChildrenInUse_1:jsonGC.Id availableGCIds:_allAvailableGCIds];
//        [self setSpinnerAdapter:sp3 jsonGCList:jsonGCArray3];
//    };
//}
//
///**
// * 注册事件——3级分类变化时，在整行选择器上保存选择了哪一个商品分类
// *
// * @param sp1
// * @param sp2
// * @param sp3
// */
///* private */ - (void) registerSpinner3Events:(TSCMySpinner *) sp1 sp2:(TSCMySpinner *)sp2 sp3:(TSCMySpinner *)sp3 {
//    sp3.itemSelectedListener = ^(TSCMySpinner * sp, UITableViewCell * cell, NSIndexPath * ip) {
//        // 获得tag
//        TSCJsonGC * jsonGC = (TSCJsonGC *) cell.myTag;
//        
//        // 在整行选择器上保存商品分类id
//        // 注：此时，view是spinner中的item：textview；parent是spinner本身；parent.getParent()是整行选择器
//        // 注（IOS）：spinner的parent就是整行选择器
//        TSCLinerLayout * selectorRow = (TSCLinerLayout *) sp.superview;
//        selectorRow.myTag = [NSNumber numberWithInt:jsonGC.Id];
//    };
//}
//
///* private */ - (void) setSpinnerAdapter:(TSCMySpinner * )spinner jsonGCList:(NSArray *)jsonGCList {
//    // 如果数据源有数据，则显示并设置adapter
//    if (jsonGCList != nil && [jsonGCList count] != 0) {
//        // 注：因调用此方法的后续代码需要立即得到spinner填充数据后的值，所以不使用异步线程准备数据
////        [spinner prepareData_P1:^{
////            // 获得商品分类名称
////            NSMutableArray * gcNameArray = [NSMutableArray array];
////            for (TSCJsonGC * jsonGC in jsonGCList) {
////                [gcNameArray addObject:jsonGC.name];
////            }
////            
////            [spinner.dataArray addObjectsFromArray:gcNameArray];
////        } completionHandler:^{
////            [spinner applyData];
////        }];
//        
//        // 将tag保存在每一个cell上
//        spinner.cellModifier = ^(UITableView * tv, UITableViewCell * cell, NSIndexPath *ip) {
//            TSCJsonGC * jsonCG = [jsonGCList objectAtIndex:ip.row];
//            cell.myTag = jsonCG;
//        };
//        
//        // 获得商品分类名称
//        NSMutableArray * gcNameArray = [NSMutableArray array];
//        for (TSCJsonGC * jsonGC in jsonGCList) {
//            [gcNameArray addObject:jsonGC.name];
//        }
//        spinner.dataArray = [NSMutableArray arrayWithArray:gcNameArray];
//        [spinner applyData];
//        
//        spinner.hidden = NO;
//    }
//    // 如果数据源无数据，则隐藏
//    else {
//        spinner.hidden = YES;
//    }
//}
//
//// 计算首行说明文字宽度（不包括右侧添加按钮） == 总宽度 - 右侧添加按钮宽度 - padding
//// 注：此方法需要在设置并应用了正确地self.frame.size.width后才能调用
///* private */ - (CGFloat) calculateLbW {
//    CGFloat selfW = self.frame.size.width;
//    if (selfW > 0) {
//        return (selfW - UI_E_H - UI_H_PADDING);
//    } else {
//        return 270; // 默认说明文字宽度 == 300 - 30
//    }
//}
//
//// 计算单个spinner的宽度 == (总宽度 - 右侧删除按钮宽度 - 3 * padding) / 3
//// 注：此方法需要在设置并应用了正确地self.frame.size.width后才能调用
///* private */ - (CGFloat) calculateSPW {
//    CGFloat selfW = self.frame.size.width;
//    if (selfW > 0) {
//        return (selfW - UI_E_H - 3 * UI_H_PADDING) / 3;
//    } else {
//        return 85; // 默认spinner宽度 == (300 - 30 - 5 * 3) / 3
//    }
//}
//
//
//#pragma mark 公共方法
//
///**
// * 创建并显示选择器行
// */
//- (void) refreshUI {
//    // 注：为了使setupViewData_1()能够运行在异步线程中，以下操作（UI操作）必须运行在UI线程中
//    
//    // 重新设置首行说明文字宽度（因为self.w可能变化了）
//    [TSCMyUIUtil setUIRect:_lbIntro x:-1 y:-1 w:[self calculateLbW] h:-1];
//    
//    // 清空所有已存在的选择器行
//    [TSCMyUIUtil removeAllSubviews:_llAddGCPanel];
//    _selectorRows = 0;
//    
//    // 指定了初始时选择的商品分类
//    if ([TSCMyUtil isStringEmpty:_selectedGCIds] == false) {
//        for (int i = 0, max = arr_count(_spIdxGCId2DArr); i < max; i++) {
//            [self addSelectorRowSelected:_spIdxGCId2DArr[i]];
//        }
//    }
//    // 没有指定初始时选择的商品分类
//    else {
//        [self addSelectorRowUnselected];
//    }
//}
//
///**
// * 依照各属性，从APP_DB中给商品分类选择器填充数据。
// *
// * @author Rio
// * @date 2014-11-06
// */
///* public */ - (void) setupViewData_1 {
//    // 过滤并检查各参数
//    _maxRows = [self filterMaxRows:_maxRows];
//    _availableGCIds = [self filterGCIds_1:_availableGCIds];
//    _selectedGCIds = [self filterGCIds_1:_selectedGCIds];
//    [self checkMaxRowsLargerSelectedGCIds];
//    [self checkSelectedGCIdsInAvailableGCIds];
//    
//    // 如果指定了可选商品分类id的范围，则需选出所有可选商品分类的父类、爷爷类，作为“合法的”商品分类id范围
//    if ([TSCMyUtil isStringEmpty:_availableGCIds] == false) {
//        _allAvailableGCIds = [TSCMyDBUtil getAllAvailableGCIds_1:_availableGCIds];
//    } else {
//        _allAvailableGCIds = @""; // 赋空值表示没有可选集的限定，所有商品分类都可以选择
//    }
//    
//    // 如果指定了默认被选择的商品分类，则需要选出各个初始时被选择商品分类的父类别、爷爷类别
//    // 注：这里无需按照1级商品分类再对mSpIdxGCId2DArr的各行进行排序，只要保证一个spinner中的各个item是按照商品分类的seq升序排列即可
//    if ([TSCMyUtil isStringEmpty:_selectedGCIds] == false) {
//        [TSCMyDBUtil getSpIdxGCId2DArr_1:_spIdxGCId2DArr gcIds:_selectedGCIds];
//    }
//    
//    // 针对于点击“增加”按钮新增的一行商品分类选择器，初始时应该如何填充，后续代码选出默认的一级、二级、三级分类
//    // 选出所有1级分类（支持限定id范围）
//    _jsonGCList1 = [TSCMyDBUtil getGoodsClassTopLevelInUse_1:_allAvailableGCIds];
//    
//    // 创建并显示选择器行
//    [self refreshUI];
//}
//
///**
// * 将用户选择的全部商品分类id以String的形式返回，后续将可能发送server
// *
// * @author Rio
// * @date 2014-11-06
// * @return 输出格式为：1,3,21
// */
///* public */ - (NSString *) getSelectedGCIdsStr {
//    NSMutableString * sb = [[NSMutableString alloc]init];
//    
//    // 循环处理每一行的商品分类选择器
//    int rows = [_llAddGCPanel.subviews count];
//    for (int i = 0; i < rows; i++) {
//        // 这一行最高级别（最精确）的商品分类id，就保存在这一行的tag上
//        TSCLinerLayout * llSelectorRow = (TSCLinerLayout *) [_llAddGCPanel.subviews objectAtIndex:i];
//        NSNumber * tag = (NSNumber *) llSelectorRow.myTag;
//        
//        if (tag != nil) {
//            int goodsClassId = [tag intValue];
//            
//            if (i < rows - 1) {
//                [sb appendString:[NSString stringWithFormat:@"%i,", goodsClassId]];
//            } else {
//                [sb appendString:[NSString stringWithFormat:@"%i", goodsClassId]];
//            }
//        } else {
//            // do nothing
//            // 没有设置tag，可能是初始时增加了空行
//        }
//    }
//    
//    return sb;
//}
//
//
///**
// * 将用户选择的全部商品分类name以list形式返回。同一行选择器中的所有spinner值，作为返回ArrayList中的一个元素。
// * 假设最多可选3个分类，且每行分类包含多级分类，可能的一种返回是：
// * <p>
// * gcName1/gcName2/gcName3
// * <p>
// * gcName4
// * <p>
// * gcName5/gcName6
// *
// * @author Rio
// * @date 2014-11-08
// * @return
// */
///* public */ - (NSArray *) getSelectedGCNameList {
//    NSMutableArray * list = [NSMutableArray array];
//    
//    // 循环处理每一行的商品分类选择器
//    // int rows = mLlAddGcPanel.getChildCount();
//    for (int i = 0; i < _selectorRows; i++) {
//        TSCLinerLayout * llSelectorRow = (TSCLinerLayout *) [_llAddGCPanel.subviews objectAtIndex:i];
//        
//        // 找到这一行的全部spinner
//        TSCMySpinner * sp1 = (TSCMySpinner *) [llSelectorRow.subviews objectAtIndex:0];
//        TSCMySpinner * sp2 = (TSCMySpinner *) [llSelectorRow.subviews objectAtIndex:1];
//        TSCMySpinner * sp3 = (TSCMySpinner *) [llSelectorRow.subviews objectAtIndex:2];
//        
//        // 拼装这一行的全部分类名称（支持多级）
//        // 注：仅处理显示（存在）的spinner
//        // 注：仅当1存在，2才可能存在；仅当2存在，3才可能存在
//        NSMutableString * sb = [[NSMutableString alloc]init];
//        if (sp1.hidden == NO) {
//            NSString * gcName1 = (NSString *) [sp1 getSelectedObject];
//            [sb appendString:gcName1];
//            
//            if (sp2.hidden == NO) {
//                NSString * gcName2 = (NSString *) [sp2 getSelectedObject];
//                [sb appendString:[NSString stringWithFormat:@"/%@", gcName2]];
//                
//                if (sp3.hidden == NO) {
//                    NSString * gcName3 = (NSString *) [sp3 getSelectedObject];
//                    [sb appendString:[NSString stringWithFormat:@"/%@", gcName3]];
//                }
//            }
//        }
//        
//        [list addObject:sb];
//    }
//    
//    return list;
//}
//
///**
// * 将商品分类名称list转换为商品分类名称描述性字符串（一个商品分类占据一行）。格式：
// * <p>
// * 1. 女鞋/女船鞋/女黑船鞋
// * <p>
// * 2. 男鞋
// * <p>
// * 3. 婴幼儿用品
// *
// * @author Rio
// * @date 2014-11-15
// *
// * @param gcNamesList
// * @return
// */
///* public */ + (NSString *) gcNameList2GcNameStr:(NSArray *) gcNamesList {
//    NSMutableString * sb = [[NSMutableString alloc]init];
//    
//    // 只有一行时，不显示序号
//    if ([gcNamesList count] == 1) {
//        [sb appendString: [gcNamesList objectAtIndex:0]];
//    }
//    // 当有多行时，显示序号，并换行
//    else {
//        for (int i = 0, max = [gcNamesList count]; i < max; i++) {
//            // 显示商品分类名称（带换行符）
//            if (i == 0) {
//                [sb appendString:[NSString stringWithFormat:@"%i.%@", i + 1, [gcNamesList objectAtIndex:i]]];
//            } else {
//                [sb appendString:[NSString stringWithFormat:@"\n%i.%@", i + 1, [gcNamesList objectAtIndex:i]]];
//            }
//        }
//    }
//    
//    return sb;
//}
//
///**
// * 通过gcIds，获得这些商品分类名称的描述性字符串（一个商品分类占据一行）。格式：
// * <p>
// * 1. 女鞋/女船鞋/女黑船鞋
// * <p>
// * 2. 男鞋
// * <p>
// * 3. 婴幼儿用品
// *
// * @author Rio
// * @date 2014-11-15
// *
// * @return 如果gcIds为空字符串，则返回空字符串；否则，返回对应的商品分类名称（s）字符串
// */
///* public */ + (NSString *) gcIds2GcPathNameStr_1:(NSString *) gcIds {
//    if ([TSCMyUtil isStringEmpty:gcIds] == true) {
//        return @"";
//    } else {
//        // 获得sp下标与商品分类信息的2维数组
//        NSArray * spIdxGC2DArr = [TSCMyDBUtil getSpIdxGC2DArr_1:gcIds];
//        
//        // 拼装商品分类名称，格式：
//        // 女鞋/船鞋/平底船鞋
//        // 女装/连衣裙
//        // 男装
//        NSMutableString * sb = [[NSMutableString alloc]init];
//        // TDDO spIdxGC2DArr有可能为nil
//        for (int i = 0, max = [spIdxGC2DArr count]; i < max; i++) {
//            // 换行符
//            if (i != 0) {
//                [sb appendString:@"\r\n"];
//            }
//            
//            NSArray * row = [spIdxGC2DArr objectAtIndex:i];
//            
//            for (int j = 0, max2 = [row count]; j < max2; j++) {
//                TSCJsonGC * gc = (TSCJsonGC *) [row objectAtIndex:j];
//                
//                // 找到一个要显示的商品分类
//                if (gc != nil) {
//                    if (j == 0) {
//                        [sb appendString:gc.name];
//                    } else {
//                        [sb appendString:[NSString stringWithFormat:@"/%@", gc.name]];
//                    }
//                }
//            }
//        }
//        
//        return sb;
//        
//        // 注：以下代码废弃，不能使用MyGoodsClassSelector重新构造，因为其中有代码是运行在UI线程上的，将导致线程同步问题
//        // // 获得商品分类的数量
//        // String[] gcIdArr = MyUtil.explode(",", gcIds);
//        
//        // // 构造一个临时的商品分类选择器，以便通过这个临时的商品分类选择器，获得已被选中商品分类的名称
//        // MyGoodsClassSelector gcSelector = new
//        // MyGoodsClassSelector(context,
//        // // maxRows：必须等于被选择商品分类的数量
//        // gcIdArr.length,
//        // // availableGCIds：空字符串
//        // "",
//        // // selectedGCIds
//        // gcIds);
//        // gcSelector.setupViewData_1();
//        
//        // 获得并返回
//        // return MyGoodsClassSelector.gcNameList2GcNameStr(gcSelector
//        // .getSelectedGCNameList());
//    }
//}
//
///**
// * 通过gcIds，获得这些商品分类名称的描述性字符串（一个商品分类占据一行）。格式：
// * <p>
// * 1. 女黑船鞋
// * <p>
// * 2. 男鞋
// * <p>
// * 3. 婴幼儿用品
// *
// * @author Rio
// * @date 2014-12-10
// *
// * @return 如果gcIds为空字符串，则返回空字符串；否则，返回对应的商品分类名称字符串
// */
///* public */ + (NSString *) gcIds2GcSingleNameStr_1:(NSString *)gcIds {
//    if ([TSCMyUtil isStringEmpty:gcIds] == true) {
//        return @"";
//    } else {
//        NSMutableString * sb = [[NSMutableString alloc]init];
//        NSArray * gcIdStrArr = [TSCMyUtil explodeString:gcIds delimiter:@","];
//        for (int i = 0, max = [gcIdStrArr count]; i < max; i++) {
//            TSCJsonGC * jsonGC = [TSCMyDBUtil getGC_1:[[gcIdStrArr objectAtIndex:i] intValue]];
//            
//            if (i != 0) {
//                [sb appendString:@","];
//            }
//            
//            [sb appendString:jsonGC.name];
//        }
//        
//        return sb;
//    }
//}
//
///**
// * 从UI界面上清除所有已选择的商品分类行，以确保在后续getSelectedGCNameList()等方法中，选出空list
// *
// * @author Rio
// * @date 2014-12-08
// */
///* public */ - (void) cleanSelectedRows {
//    // 清空所有已存在的选择器行
//    [TSCMyUIUtil removeAllSubviews:_llAddGCPanel];
//    _selectorRows = 0;
//}
//
//
//@end
//
//
//
//@implementation InnerObserverGCSelectorWH {
//    TSCMyGCSelector * _gc;
//}
//
//- (id) initWithGCSelector:(TSCMyGCSelector *)gcSelector {
//    self = [super init];
//    if (self) {
//        _gc = gcSelector;
//        
//        // 设置监听者
//        [_gc addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
//        [_gc addObserver:self forKeyPath:@"bounds" options:NSKeyValueObservingOptionNew context:nil];
//    }
//    return self;
//}
//
//- (void) removeObserver {
//    [_gc removeObserver:self forKeyPath:@"frame"];
//    [_gc removeObserver:self forKeyPath:@"bounds"];
//}
//
//- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
//    if ([keyPath isEqualToString:@"frame"] || [keyPath isEqualToString:@"bounds"]) {
//        [_gc refreshUI];
//    }
//}



//@end
